Skip to content

Comments

detect/cip: add check for sscanf return-value - v5#10433

Closed
0xEniola wants to merge 1 commit intoOISF:masterfrom
0xEniola:detect-cip-6753-v5
Closed

detect/cip: add check for sscanf return-value - v5#10433
0xEniola wants to merge 1 commit intoOISF:masterfrom
0xEniola:detect-cip-6753-v5

Conversation

@0xEniola
Copy link
Contributor

Link to redmine ticket: https://redmine.openinfosecfoundation.org/issues/6753

Previous PR: #10418

Describe changes:

  • Format specifier used on message for SCLogError re: sscanf [line 161] was wrong.

Found by CodeQL.
Cf https://codeql.github.com/codeql-query-help/cpp/cpp-missing-check-scanf/

The sscanf function returns the number of input items successfully matched
and assigned.

We have to ensure that all subsequent uses of scanf output arguments occur in
a branch of an if statement (or similar), in which it is known that the
corresponding scanf call has in fact read all possible items from its input.
Hence, we always have to check if sscanf runs successfully by comparing
the return value to a numerical constant.

Ticket: 6753
@victorjulien
Copy link
Member

Can you show some examples of Suricata's output with malformed rules that display this error?

@0xEniola
Copy link
Contributor Author

Can you show some examples of Suricata's output with malformed rules that display this error?

When I tested using unit tests, I found out with all the inputs I tried, the checks in the while case at line 113, caught all wrong user inputs before getting to the sscanf part, so there was no point where it got triggered.

@0xEniola
Copy link
Contributor Author

0xEniola commented Feb 18, 2024

Can you show some examples of Suricata's output with malformed rules that display this error?

Had to remove the other if and else if statements in the while statement, and left only the one with sscanf.

Test DetectCipServiceParseTest01                                  : Debug: time: offline time mode enabled [TimeModeSetOffline:util-time.c:108]
Debug: time: time set to 1708245819 sec, 436821 usec [TimeSet:util-time.c:133]
Error: detect-cipservice: incorrect input format; token xxmp should be uint8 [DetectCipServiceParse:detect-cipservice.c:116]
Debug: detect-cipservice: Returning pointer (nil) of type DetectENIP ... << [DetectCipServiceParse:detect-cipservice.c:150]
FAILED
==== TEST RESULTS ====
PASSED: 0
FAILED: 1
======================```

@0xEniola
Copy link
Contributor Author

0xEniola commented Feb 18, 2024

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

@jufajardini jufajardini added the decision-required Waiting on deliberation from the team label Feb 21, 2024
@jufajardini
Copy link
Contributor

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

@0xEniola
Copy link
Contributor Author

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

Yes, could will be better.
Thank you for the sugestion.

I tried comma seperated inputs, and it did not work though.
So, I really do not know.

@jufajardini
Copy link
Contributor

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

Yes, could will be better. Thank you for the sugestion.

I tried comma seperated inputs, and it did not work though. So, I really do not know.

Can you elaborate on how did you try that?

@0xEniola
Copy link
Contributor Author

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

I feel I also need to change the error message to incorrect input format; token "???" can not be converted to uint8 instead.

Minor suggestion: could instead of can not

I'm also wondering why sscanf was not made to be at the beginning of the while case to be sure the input can be converted to uint8 first before performing the other checks.

I'm guessing that this might be to ensure the input is a list of integers comma-separated. But not sure.

Yes, could will be better. Thank you for the sugestion.
I tried comma seperated inputs, and it did not work though. So, I really do not know.

Can you elaborate on how did you try that?

I did it via the unittests, but I guess I did it wrong before; I tried it again now, and it works.

}

sscanf(token, "%2" SCNu8, &var);
if (sscanf(token, "%2" SCNu8, &var) != 1) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it looks like the original code has some serious issues, c5cf296 broke things by turning the input array into a uint8_t array, even though for class and attribute we're supposed to have a uint16_t values. So that would need fixing.

In general, on further inspection, it's unclear why we have the sscanf at all. We already have num, and it's value is validated to be in range, so we can safely cast it to uint8_t for service and uint16_t for the other two.

cc @catenacyber

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Complementing this: a good thing to have to go along the next PR for this would be a Suricata-verify PR that used the cip.class and cip.attribute keywords with values that would not fit a u8 so we check that this is working as expected.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed thanks for the analysis Victor.

We can remove the call to sscanf and use num instead of var

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to remove sscanf and do input[i++] = num; then.

And do an SV test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and pay attention to use the right integer types uint16 and uint8 ;-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant on the Suricata patch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh! I thought I'm only to modify the sscanf part and the input[i++] = var part.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some compilers will warn on input[i++] = num;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So to change the definition if the input array to uint16_t then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed

Copy link
Member

@victorjulien victorjulien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see inline discussion

@catenacyber
Copy link
Contributor

Stale PR
Proposing to use #10901 which will fix it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

decision-required Waiting on deliberation from the team

Development

Successfully merging this pull request may close these issues.

4 participants